package com.un.ebs.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.un.ebs.core.enums.IndustryTypeEnum;
import com.un.ebs.core.enums.UserTypeEnum;
import com.un.ebs.core.exception.BusinessEntityNotFoundException;
import com.un.ebs.core.exception.BusinessException;
import com.un.ebs.core.util.SecurityUtils;
import com.un.ebs.core.util.StringUtils;
import com.un.ebs.order.OrderConfigureCode;
import com.un.ebs.product.domain.*;
import com.un.ebs.product.dto.ProductDto;
import com.un.ebs.product.dto.ProductSkuByUpdateDto;
import com.un.ebs.product.dto.ProductSkuVo;
import com.un.ebs.product.dto.SkuItemUpdateDto;
import com.un.ebs.product.enums.ProductBomTypeEnum;
import com.un.ebs.product.enums.ProductUnitTypeEnum;
import com.un.ebs.product.enums.ProductValueExpressionTypeEnum;
import com.un.ebs.product.mapper.*;
import com.un.ebs.product.service.ProductClassAttrService;
import com.un.ebs.product.service.ProductImageService;
import com.un.ebs.product.service.ProductService;
import com.un.ebs.product.service.ProductSkuService;
import com.un.ebs.sys.dto.ObjectParentAndIndexChangeDto;
import com.un.ebs.sys.service.ConfigureService;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author liubo
 * @since 2019-09-16
 */
@Service
public class ProductSkuServiceImpl extends ServiceImpl<ProductSkuMapper, ProductSku> implements ProductSkuService {

    @Resource
    private ProductSkuMapper productSkuMapper;

    @Resource
    private ProductSkuExtMapper productSkuExtMapper;

    @Resource
    private ConfigureService configureService;

    @Resource
    private ProductClassAttrService productClassAttrService;

    @Resource
    private ProductSkuAttrValueExtMapper productSkuAttrValueExtMapper;

    @Resource
    private ProductSkuPurchaseCountExtMapper productSkuPurchaseCountExtMapper;

    @Resource
    private ProductBomExtMapper productBomExtMapper;

    @Resource
    private ProductSkuItemMapper productSkuItemMapper;

    @Resource
    private ProductSkuItemExtMapper productSkuItemExtMapper;

    @Resource
    private ProductBomCostExtMapper productBomCostExtMapper;

    @Resource
    private ProductBomCostItemExtMapper productBomCostItemExtMapper;

    @Resource
    private ProductAttrValueExtMapper productAttrValueExtMapper;

    @Resource
    private ProductImageService productImageService;

    @Resource
    private ProductService productService;

    @Resource
    private SkuExtMapper skuExtMapper;

    @Resource
    private ProductSaleQueryByTombMapper productSaleQueryByTombMapper;

    @Resource
    private ProductMapper productMapper;

    @Override
    public void update(String id, String code, Double price, Boolean isVirtual, Boolean isPriceConfer) {
        ProductSku obj = getById(id);
        obj.setPrice(price);
        if (!StringUtils.isNullOrEmpty(code)) {
            obj.setSkuCode(code);
        }
        if (isVirtual != null) {
            obj.setIsVirtual(isVirtual);
        }
        if (isPriceConfer != null) {
            obj.setIsPriceConfer(isPriceConfer);
        }
        obj.updateById();
    }

    @Override
    public void addInclude(String id, String includeSkuId, Double qty, ProductBomTypeEnum bomType) {
        if (bomType == null) {
            bomType = ProductBomTypeEnum.Default;
        }

        LambdaQueryWrapper<ProductSkuItem> lq = Wrappers.lambdaQuery();
        lq.eq(ProductSkuItem::getSkuId, id);
        lq.eq(ProductSkuItem::getIncludeSkuId, includeSkuId);
        lq.eq(ProductSkuItem::getBomType, bomType);
        int cnt = productSkuItemMapper.selectCount(lq);
        if (cnt <= 0) {
            ProductSkuItem item = new ProductSkuItem();
            item.setSkuId(id);
            item.setIncludeSkuId(includeSkuId);
            item.setQty(qty);
            item.setIsDelete(false);
            item.setBomType(bomType);
            item.insert();
        } else {
            ProductSkuItem skuItem = productSkuItemMapper.selectOne(lq);
            skuItem.setQty(qty);
            skuItem.setBomType(bomType);
            skuItem.updateById();
        }
    }

    private SkuExt queryByCode(String code) {
        LambdaQueryWrapper<SkuExt> lq = Wrappers.lambdaQuery();
        lq.eq(SkuExt::getSkuCode, code);
        lq.eq(SkuExt::getIsDelete, false);
        if (skuExtMapper.selectCount(lq) > 1) {
            throw new BusinessException(String.format("物料编码【%s】重复，请先处理后再进行此操作。", code));
        }
        return skuExtMapper.selectOne(lq);
    }

    @Override
    public void addIncludeByCode(String id, String skuCode, Double qty, ProductBomTypeEnum bomType) {
        if (bomType == null) {
            throw new BusinessException("请指定Bom类型。");
        }
        SkuExt sku = queryByCode(skuCode);
        if (sku == null) {
            throw new BusinessEntityNotFoundException(skuCode, "SKU");
        }
        addInclude(id, sku.getSkuId(), qty, bomType);
    }

    @Override
    public void removeInclude(String id) {
        ProductSkuItem item = productSkuItemMapper.selectById(id);
        if (item == null) {
            return;
        }

        LambdaQueryWrapper<ProductSkuItem> lq = Wrappers.lambdaQuery();
        lq.eq(ProductSkuItem::getParentId, item.getId());
        List<ProductSkuItem> childs = productSkuItemMapper.selectList(lq);
        for (ProductSkuItem child : childs) {
            if (com.un.ebs.core.util.StringUtils.isNullOrEmpty(item.getParentId())) {
                child.setParentId(null);
            } else {
                child.setParentId(item.getParentId());
            }
            child.updateById();
        }

        productSkuItemMapper.deleteById(id);
    }

    @Override
    public void removeInclude(String id, String includeSkuId) {
        LambdaQueryWrapper<ProductSkuItem> lq = Wrappers.lambdaQuery();
        lq.eq(ProductSkuItem::getSkuId, id);
        lq.eq(ProductSkuItem::getIncludeSkuId, includeSkuId);
        productSkuItemMapper.delete(lq);
    }

    @Override
    public void updateIncludeQty(String id, Double qty) {
        ProductSkuItem item = productSkuItemMapper.selectById(id);
        if (item == null) {
            throw new BusinessEntityNotFoundException(id, "Sku Item");
        }

        item.setQty(qty);
        item.updateById();
    }

    @Override
    public void updateSkuItem(SkuItemUpdateDto req) {
        ProductSkuItem item = productSkuItemMapper.selectById(req.getItemId());
        if (item == null) {
            throw new BusinessEntityNotFoundException(req.getItemId(), "Sku Item");
        }

        item.setQty(req.getUserQty());
        //item.setIsAllowLackStart(req.getAllowLackStart());
        if (req.getDeliverType() != null) {
            item.setDeliverType(req.getDeliverType());
        }
        if (req.getBomType() != null) {
            item.setBomType(req.getBomType());
        }

        item.updateById();

        if (req.getPurchaseType() != null) {
            ProductSkuExt sku = queryViewById(item.getIncludeSkuId());
            if (sku == null) {
                throw new BusinessEntityNotFoundException(item.getIncludeSkuId(), "SKU");
            }
            Product spu = productMapper.selectById(sku.getProductId());
            if (spu == null) {
                throw new BusinessEntityNotFoundException(sku.getProductId(), "SPU");
            }
            spu.setPurchaseType(req.getPurchaseType());
            spu.updateById();
        }

    }

    @Override
    public void updateSku(ProductSkuByUpdateDto req) {
        ProductSku sku;
        SkuExt skuExits = queryByCode(req.getCode());
        if (StringUtils.isNullOrEmpty(req.getId())) {

            if (skuExits != null) {
                throw new BusinessException("编码不能重复。");
            }

            ProductDto spu = new ProductDto();
            spu.setCode(req.getCode());
            spu.setName(req.getName());
            spu.setPurchaseType(req.getPurchaseType());
            spu.setPrice(req.getPrice());
            spu.setClassId(req.getClassId());
            spu.setUnitType(ProductUnitTypeEnum.ProductQty);
            String id = productService.add(spu, true);

            LambdaQueryWrapper<ProductSku> lq = Wrappers.lambdaQuery();
            lq.eq(ProductSku::getProductId, id);
            for (ProductSku obj : baseMapper.selectList(lq)) {
                obj.setProductionSeqId(req.getSeqId());
                obj.updateById();
            }
        } else {
            if (skuExits != null) {
                if (!skuExits.getSkuId().equals(req.getId())) {
                    throw new BusinessException("编码不能重复。");
                }
            }
            sku = baseMapper.selectById(req.getId());
            if (sku == null) {
                throw new BusinessEntityNotFoundException(req.getId(), "SKU");
            }
            Product spu = productMapper.selectById(sku.getProductId());
            if (spu == null) {
                throw new BusinessEntityNotFoundException(sku.getProductId(), "SPU");
            }
            spu.setCode(req.getCode());
            spu.setName(req.getName());
            spu.setPurchaseType(req.getPurchaseType());
            spu.setPrice(req.getPrice());
            spu.setClassId(req.getClassId());
            spu.setUnitType(ProductUnitTypeEnum.ProductQty);
            spu.updateById();

            sku.setSkuCode(req.getCode());
            sku.setPrice(req.getPrice());
            sku.setProductionSeqId(req.getSeqId());
            sku.updateById();
        }
    }

    @Override
    public void updateCostPrice(String skuId, Double costPrice) {
        ProductSku sku = baseMapper.selectById(skuId);
        if (sku == null) {
            throw new BusinessEntityNotFoundException(skuId, "SKU");
        }

        sku.setCostPrice(costPrice);
        sku.updateById();
    }

    @Override
    public void updateLackStatus(String id, Boolean allowStatus) {
        LambdaQueryWrapper<ProductSkuItem> lq = Wrappers.lambdaQuery();
        lq.eq(ProductSkuItem::getSkuId, id);
        for (ProductSkuItem item : productSkuItemMapper.selectList(lq)) {
            item.setIsAllowLackStart(allowStatus);
            item.updateById();
        }
    }

    @Override
    public void updateLackStatusByItemId(List<String> ids, Boolean allowStatus) {
        for (String id : ids) {
            LambdaQueryWrapper<ProductSkuItem> lq = Wrappers.lambdaQuery();
            ProductSkuItem item = productSkuItemMapper.selectById(id);
            if (item != null) {
                item.setIsAllowLackStart(allowStatus);
                item.updateById();
            }
        }
    }

    @Override
    public ProductSku queryById(String id) {
        return productSkuMapper.selectById(id);
    }

    @Override
    public ProductSkuVo queryViewById(String id) {
        ProductSkuExt productSkuExt = baseMapper.selectNotTenantIdById(id);
        if (productSkuExt == null) {
            return null;
        }
        return convertVo(productSkuExt);
    }

    @Override
    public ProductSkuVo queryBySaleAttr(String id, String saleAttr) {
        ProductSkuExt sku;
        if (StringUtils.isNullOrEmpty(saleAttr)) {
            sku = baseMapper.selectNotTenantBySpu(id);
        } else {
            sku = baseMapper.selectNotTenant(id, saleAttr);
        }
        if (sku == null) {
            throw new BusinessException("SKU 没有找到。");
        }
        return convertVo(sku);

    }

    @Override
    public String queryDeliverTimePeriodExpression(String id) {
        LambdaQueryWrapper<ProductSkuAttrValueExt> lq = Wrappers.lambdaQuery();
        lq.eq(ProductSkuAttrValueExt::getProductSkuId, id);
        lq.eq(ProductSkuAttrValueExt::getAttrExpressionType, ProductValueExpressionTypeEnum.TimePeriod);
        if (productSkuAttrValueExtMapper.selectCount(lq) > 1) {
            log.error("配置错误，SKU" + id + "不能同时有1个以上的相同类型的属性表达式。");
            throw new BusinessException("配置错误，SKU" + id + "不能同时有1个以上的相同类型的属性表达式。");
        }
        ProductSkuAttrValueExt ret = productSkuAttrValueExtMapper.selectOne(lq);
        if (ret != null) {
            return ret.getAttrExpression();
        } else {
            return null;
        }
    }

    private ProductSkuVo convertVo(ProductSkuExt skuExt) {
        ProductSkuVo result = new ProductSkuVo();
        BeanUtils.copyProperties(skuExt, result);

        result.setImages(productImageService.queryBySpuId(skuExt.getProductId()));
        result.setSkuItem(queryItemBySkuId(skuExt.getId()));

        // 查询 SKU 属性，也就是销售属性
        LambdaQueryWrapper<ProductSkuAttrValueExt> query = Wrappers.lambdaQuery();
        query.eq(ProductSkuAttrValueExt::getProductSkuId, skuExt.getId());
        query.orderByAsc(ProductSkuAttrValueExt::getSort);
        result.setAttrValues(productSkuAttrValueExtMapper.selectList(query));

        // 查询非销售属性
        LambdaQueryWrapper<ProductAttrValueExt> spuAttr = Wrappers.lambdaQuery();
        spuAttr.eq(ProductAttrValueExt::getProductId, skuExt.getProductId());
        spuAttr.eq(ProductAttrValueExt::getIsSale, false);
        List<String> attrIds = result.getAttrValues().stream().map(s -> s.getAttrId()).collect(Collectors.toList());
        if (!com.un.ebs.core.util.StringUtils.isNullOrEmpty(attrIds)) {
            spuAttr.notIn(ProductAttrValueExt::getAttrId, attrIds);
        }

        result.getAttrValues().addAll(productAttrValueExtMapper.selectList(spuAttr).stream().map(s -> {
            ProductSkuAttrValueExt obj = new ProductSkuAttrValueExt();
            obj.setId(s.getId());
            obj.setAttrId(s.getAttrId());
            obj.setAttrName(s.getAttrName());
            obj.setAttrValue(s.getAttrValue());
            obj.setIsColumnShow(s.getIsColumnShow());
            obj.setIsKey(s.getIsKey());
            obj.setIsMulti(s.getIsMulti());
            obj.setIsMust(s.getIsMust());
            obj.setIsSale(s.getIsSale());
            return obj;
        }).distinct().collect(Collectors.toList()));

        return result;
    }

    @Override
    public void bindQrcode(String id, String qrcode) {
        if (SecurityUtils.getUserContent().getType() == UserTypeEnum.OTHER) {
            throw new BusinessException("你的账号类型[" + SecurityUtils.getUserContent().getType() + "]不能进行此操作。");
        }
        ProductSku obj = baseMapper.selectById(id);
        obj.setQrcode(qrcode);
        obj.updateById();
    }

    @Override
    public ProductSkuVo queryByQrcode(String qrcode) {
        ProductSkuExt ret = baseMapper.selectByQrcode(qrcode);
        if (ret != null) {
            return convertVo(ret);
        } else {
            return null;
        }
    }

    @Override
    public IPage<ProductSaleQueryByTomb> querySaleByTomb(String searchText, String classId, int pageSize, int pageIndex) {
        Page<ProductSaleQueryByTomb> page = new Page(pageIndex, pageSize);
        LambdaQueryWrapper<ProductSaleQueryByTomb> lq = Wrappers.lambdaQuery();
        if (!StringUtils.isNullOrEmpty(searchText)) {
            lq.like(ProductSaleQueryByTomb::getSkuNameAs, searchText).or()
                    .like(ProductSaleQueryByTomb::getCustName, searchText).or()
                    .like(ProductSaleQueryByTomb::getDefunctNames, searchText).or()
                    .like(ProductSaleQueryByTomb::getLinkmanPhone, searchText);
        }
        if (!StringUtils.isNullOrEmpty(classId)) {
            List<String> ids = productClassAttrService.queryClassChildIds(classId);
            if (StringUtils.isNullOrEmpty(ids)) {
                lq.eq(ProductSaleQueryByTomb::getClassId, classId);
            } else {
                lq.in(ProductSaleQueryByTomb::getClassId, ids);
            }
        }
        return productSaleQueryByTombMapper.selectPage(page, lq);
    }

    @Override
    public IPage<SkuExt> querySku(String searchText, String classId, int pageSize, int pageIndex) {
        Page<SkuExt> page = new Page(pageIndex, pageSize);
        LambdaQueryWrapper<SkuExt> lq = Wrappers.lambdaQuery();
        if (!StringUtils.isNullOrEmpty(searchText)) {
            lq.like(SkuExt::getSkuCode, searchText).or().like(SkuExt::getSkuName, searchText);
        }
        if (!StringUtils.isNullOrEmpty(classId)) {
            if (classId.split(",").length > 1) {
                lq.in(SkuExt::getClassId, classId.split(","));
            } else {
                lq.eq(SkuExt::getClassId, classId);
            }
        }
        lq.orderByAsc(SkuExt::getSkuCode);
        return skuExtMapper.selectPage(page, lq);
    }

    @Override
    public List<ProductSkuItemExt> queryItemBySkuId(String id) {
        return productSkuItemExtMapper.queryBySkuId(id);
    }

    @Override
    public IPage<ProductSkuItemExt> queryItemBySkuId(String id, ProductBomTypeEnum bomType, int pageSize, int pageIndex) {
        Page<ProductSkuItemExt> page = new Page(pageIndex, pageSize);
        LambdaQueryWrapper<ProductSkuItemExt> lq = Wrappers.lambdaQuery();
        lq.eq(ProductSkuItemExt::getSkuId, id);
        lq.eq(ProductSkuItemExt::getIsDelete, false);
        if (bomType != null) {
            lq.eq(ProductSkuItemExt::getBomType, bomType);
        }
        if (SecurityUtils.getUserContent().getIndustryType() == IndustryTypeEnum.FuneralAndInterment) {
            lq.orderByAsc(ProductSkuItemExt::getSort);
        } else {
            lq.orderByAsc(ProductSkuItemExt::getSkuCode);
        }

        return productSkuItemExtMapper.selectPage(page, lq);

    }

    @Override
    public ProductSkuItemExt queryItemById(String id) {
        return productSkuItemExtMapper.selectById(id);
    }

    @Override
    public IPage<ProductSkuExt> query(String searchText, int pageSize, int pageIndex) {
        return query(searchText, null, null, null, null, pageSize, pageIndex);
    }

    @Override
    public IPage<ProductBomExt> queryBom(String searchText, int pageSize, int pageIndex) {
        Page<ProductBomExt> page = new Page<>(pageIndex, pageSize);
        LambdaQueryWrapper<ProductBomExt> lq = Wrappers.lambdaQuery();
        if (!StringUtils.isNullOrEmpty(searchText)) {
            lq.like(ProductBomExt::getSkuCode, searchText).or()
                    .like(ProductBomExt::getSkuName, searchText).or()
                    .like(ProductBomExt::getBomSkuCode, searchText).or()
                    .like(ProductBomExt::getBomSkuName, searchText);
        }
        lq.eq(ProductBomExt::getIsDelete, false);
        lq.orderByAsc(ProductBomExt::getSkuCode).orderByAsc(ProductBomExt::getBomSkuCode);
        return productBomExtMapper.selectPage(page, lq);
    }

    @Override
    public List<ProductBomExt> queryBomBySku(String skuId) {
        LambdaQueryWrapper<ProductBomExt> lq = Wrappers.lambdaQuery();
        lq.eq(ProductBomExt::getSkuId, skuId);
        lq.eq(ProductBomExt::getIsDelete, false);
        lq.orderByAsc(ProductBomExt::getBomSkuCode);
        return productBomExtMapper.selectList(lq);
    }

    @Override
    public List<ProductBomExt> queryBomBySku(String skuId, ProductBomTypeEnum bomType) {
        LambdaQueryWrapper<ProductBomExt> lq = Wrappers.lambdaQuery();
        lq.eq(ProductBomExt::getSkuId, skuId);
        lq.eq(ProductBomExt::getIsDelete, false);
        if (bomType != null) {
            //lq.eq(gett)
        }
        lq.orderByAsc(ProductBomExt::getBomSkuCode);
        return productBomExtMapper.selectList(lq);
    }

    @Override
    public IPage<ProductSkuExt> query(String searchText, String classId, String productId, Boolean isCanSale, Boolean isMain, int pageSize, int pageIndex) {
        Page<ProductSkuExt> page = new Page<>(pageIndex, pageSize);
        LambdaQueryWrapper<ProductSkuExt> query = Wrappers.lambdaQuery();
        query.eq(ProductSkuExt::getIsDelete, false);
        query.eq(ProductSkuExt::getSpuIsDelete, false);

        if (!com.un.ebs.core.util.StringUtils.isNullOrEmpty(searchText)) {
            query.and(s -> s.like(ProductSkuExt::getClassName, searchText).or()
                    .like(ProductSkuExt::getName, searchText).or()
                    .like(ProductSkuExt::getSpuCode, searchText).or()
                    .like(ProductSkuExt::getSaleAttrDesc, searchText));
        }
        if (!StringUtils.isNullOrEmpty(classId)) {
            query.eq(ProductSkuExt::getClassId, classId);
        }
        if (!StringUtils.isNullOrEmpty(productId)) {
            query.eq(ProductSkuExt::getProductId, productId);
        }
        if (isCanSale != null) {
            if (isCanSale) {
                query.eq(ProductSkuExt::getIsSpuSale, true);
                query.eq(ProductSkuExt::getIsSkuSale, true);
            }
        }
        if (isMain != null) {
            if (isMain) {
                String rootClassId = configureService.getValueByCode(OrderConfigureCode.tomb_spu_class_id, SecurityUtils.getTenantId());
                if (!StringUtils.isNullOrEmpty(rootClassId)) {
                    String sql = null;
                    for (String id : rootClassId.split(",")) {
                        if (StringUtils.isNullOrEmpty(sql)) {
                            sql = " class_root_name like '%" + id + "%'";
                        } else {
                            sql += " or class_root_name like '%" + id + "%'";
                        }
                    }
                    query.apply("(" + sql + ")");
                }
            } else {
                String rootClassId = configureService.getValueByCode(OrderConfigureCode.tomb_spu_class_id, SecurityUtils.getTenantId());
                query.like(ProductSkuExt::getClassRootName, rootClassId);
            }
        }
        query.orderByAsc(ProductSkuExt::getSkuIdx);
        return productSkuExtMapper.selectPage(page, query);
    }

    @Override
    public IPage<ProductSkuExt> queryByMain(String searchText, int pageSize, int pageIndex) {
        return query(searchText, null, null, null, true, pageSize, pageIndex);
    }

    @Override
    public IPage<ProductSkuExt> queryByOther(String searchText, int pageSize, int pageIndex) {
        return null;
    }

    @Override
    public IPage<ProductSkuPurchaseCountExt> queryPurchaseCount(String searchText, Boolean notSupply, int pageSize, int pageIndex) {
        Page<ProductSkuPurchaseCountExt> page = new Page(pageIndex, pageSize);
        LambdaQueryWrapper<ProductSkuPurchaseCountExt> lq = Wrappers.lambdaQuery();
        if (!StringUtils.isNullOrEmpty(searchText)) {
            lq.like(ProductSkuPurchaseCountExt::getSkuCode, searchText).or()
                    .like(ProductSkuPurchaseCountExt::getName, searchText);
        }
        if (notSupply != null) {
            if (notSupply) {
                lq.eq(ProductSkuPurchaseCountExt::getSupplyCount, 0);
            }
        }
        return productSkuPurchaseCountExtMapper.selectPage(page, lq);
    }

    @Override
    public void delete(String id) {
        ProductSku sku = baseMapper.selectById(id);
        if (sku != null) {
            if (productMapper.selectInventoryQty(sku.getProductId())>0){
                throw new BusinessException("库存不为零，不可以删除。");
            }
            List<ProductSkuItemExt> skuItems = baseMapper.selectItemCountBySku(id);
            if (skuItems.size() > 0) {
                String skuName = productMapper.selectById(sku.getProductId()).getName();
                String skuNames = skuItems.stream().map(s -> s.getNameAs()).collect(Collectors.joining(","));
                throw new BusinessException(String.format("【%s】已被用于【%s】产品BOM中，需要先行删除后才能执行此操作。", skuName, skuNames));
            }
            LambdaQueryWrapper<ProductSku> lq = Wrappers.lambdaQuery();
            lq.eq(ProductSku::getProductId, sku.getProductId());
            if (baseMapper.selectCount(lq) <= 1) {
                baseMapper.delete(lq);
            } else {
                baseMapper.deleteById(id);
            }
        }
    }

    @Override
    public void upperShelf(String id) {
        ProductSku productSku = getById(id);
        if (productSku == null) {
            throw new BusinessEntityNotFoundException(id, "sku");
        }

        if (productSku.getIsSale()) {
            return;
        }

        productSku.setIsSale(true);
        productSku.updateById();
    }

    @Override
    public void lowerShelf(String id) {
        ProductSku productSku = getById(id);
        if (productSku == null) {
            throw new BusinessEntityNotFoundException(id, "sku");
        }

        if (!productSku.getIsSale()) {
            return;
        }

        productSku.setIsSale(false);
        productSku.updateById();
    }

    @Override
    public void changeNode(List<ObjectParentAndIndexChangeDto> nodes) {
        for (ObjectParentAndIndexChangeDto node : nodes) {
            ProductSkuItem item = productSkuItemMapper.selectById(node.getId());
            item.setParentId(node.getParentId());
            item.setSort(node.getIndex());
            item.updateById();
        }
    }

    @Override
    public IPage<ProductBomCostExt> queryBomCost(String skuCode, int pageSize, int pageIndex) {
        Page<ProductBomCostExt> page = new Page<>(pageIndex, pageSize);
        LambdaQueryWrapper<ProductBomCostExt> lq = Wrappers.lambdaQuery();
        if (!StringUtils.isNullOrEmpty(skuCode)) {
            lq.eq(ProductBomCostExt::getSkuCode, skuCode.trim());
        }
        lq.orderByAsc(ProductBomCostExt::getSkuCode);
        return productBomCostExtMapper.selectPage(page, lq);
    }

    @Override
    public IPage<ProductBomCostItemExt> queryBomItemCost(String skuId, String bomSkuCode, int pageSize, int pageIndex) {
        Page<ProductBomCostItemExt> page = new Page<>(pageIndex, pageSize);
        LambdaQueryWrapper<ProductBomCostItemExt> lq = Wrappers.lambdaQuery();
        if(!StringUtils.isNullOrEmpty(skuId)){
            lq.eq(ProductBomCostItemExt::getSkuId, skuId);
        }
        if (!StringUtils.isNullOrEmpty(bomSkuCode)) {
            lq.eq(ProductBomCostItemExt::getBomSkuCode, bomSkuCode);
        }
        lq.orderByAsc(ProductBomCostItemExt::getBomSkuCode);
        return productBomCostItemExtMapper.selectPage(page, lq);
    }
}